#include <iostream>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <fstream>
#include <sstream>
#include <bitset>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/can.h>
#include <linux/can/raw.h>

using namespace std;

#define CAN_INTERFACE "can0"     //设置CAN口

int main()
{
    struct sockaddr_can addr;
    struct ifreq ifr;
    struct can_frame frame;
    int s;

    if((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0)        //创建套接字
    {
        perror("Socket");
        return -1;
    }

    strcpy(ifr.ifr_name, CAN_INTERFACE);
    ioctl(s, SIOCGIFINDEX, &ifr);

    addr.can_family = AF_CAN;
    addr.can_ifindex = ifr.ifr_ifindex;
    bind(s, (struct sockaddr*)&addr, sizeof(addr));

    int pid = 0x00;        //设置PID

    frame.can_id = 0x7DF;       //发送请求帧
    frame.can_dlc = 0x08;
    frame.data[0] = 0x02;
    frame.data[1] = 0x01;
    frame.data[2] = pid;
    frame.data[3] = 0x00;
    frame.data[4] = 0x00;
    frame.data[5] = 0x00;
    frame.data[6] = 0x00;
    frame.data[7] = 0x00;
    write(s, &frame, sizeof(struct can_frame));

    bool flag = true;       //读取响应帧

    while(flag)
    {
        struct can_frame rframe;
        int recvbytes = read(s, &rframe, sizeof(struct can_frame));

        if(recvbytes)
        {
            if(rframe.can_id == 0x7E8)
            {
                cout << "Response frame received!" << endl;
                cout << hex << (int)rframe.data[3] << endl;     //解析响应数据
                flag = false;
            }
        }
    }

    close(s);
    return 0;
}
